/* AMX Mod X
*   Nextmap Chooser Plugin
*
* by the AMX Mod X Development Team
*  originally developed by OLO
*
* This file is part of AMX Mod X.
*
*
*  This program is free software; you can redistribute it and/or modify it
*  under the terms of the GNU General Public License as published by the
*  Free Software Foundation; either version 2 of the License, or (at
*  your option) any later version.
*
*  This program is distributed in the hope that it will be useful, but
*  WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
*  General Public License for more details.
*
*  You should have received a copy of the GNU General Public License
*  along with this program; if not, write to the Free Software Foundation,
*  Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*  In addition, as a special exception, the author gives permission to
*  link the code of this program with the Half-Life Game Engine ("HL
*  Engine") and Modified Game Libraries ("MODs") developed by Valve,
*  L.L.C ("Valve"). You must obey the GNU General Public License in all
*  respects for all of the code used other than the HL Engine and MODs
*  from Valve. If you modify this file, you may extend this exception
*  to your version of the file, but you are not obligated to do so. If
*  you do not wish to do so, delete this exception statement from your
*  version.
*/
////////////////////////////////////////////////////////////////////////
//                           ***EDITED***
//
//   diamond-optic
//   mod version 0.4
//   02.10.07
//
//
// Info:
//	- Specifically modified for AvaMods
//
//	- will show current map on vote list
//	- extend choice is shown on top & bottom
//	- seperate extend step for ava & hill
//	- sepetate max step for hill
//	- places 'modified' before each map name
//	- colored menu
//	- changed spk message
//	- cancel vote using amx_cancelmapvote
//	- Avalanche will always be #1 on list if current map is not avalanche
//
//
// Change Log:
//
//	- 07.24.2006 Mod Version 0.1b
//		Fixed mistake with extend map parts
//
//	- 09.25.2006 Mod Version 0.1c
//		Removed showing current map in vote list
//
//	- 11.16.2006 Mod Version 0.2
//		Added command to cancel end of map vote
//
//	- 12.25.2006 Mod Version 0.3
//		added amxx 1.76c changes
//
//	- 02.10.2006 Mod Version 0.4
//		If the current map is not avalanche, avalanche will be #1 on the list
//
////////////////////////////////////////////////////////////////////////

#include <amxmodx>
#include <amxmisc>

#define MAX_MAPS    128
#define SELECTMAPS  8

new g_mapName[MAX_MAPS][32]
new g_mapNums

new g_nextName[SELECTMAPS]
new g_voteCount[SELECTMAPS + 2]
new g_mapVoteNum
new g_teamScore[2]
new g_lastMap[32]

new g_coloredMenus
new bool:g_selected = false

public plugin_init()
{
	register_plugin("avamods mapchooser", "0.4", "AMXX Dev Team & diamond-optic")
	
	register_cvar("avamods_mapchooser_stats", "0.4", FCVAR_SERVER|FCVAR_SPONLY)
	
	register_dictionary("mapchooser.txt")
	register_dictionary("common.txt")
	register_dictionary("adminvote.txt")
	
	new MenuName[64]
	
	format(MenuName, 63, "%L", "en", "CHOOSE_NEXTM")
	register_menucmd(register_menuid(MenuName), (-1^(-1<<(SELECTMAPS+2))), "countVote")
	register_cvar("amx_extendmap_max", "360")
	register_cvar("amx_extendmap_step", "30")
	register_cvar("amx_extendmap_max2", "720")
	register_cvar("amx_extendmap_step2", "60")
	
	register_concmd("amx_cancelmapvote", "cmdCancelVote", ADMIN_LEVEL_B, "- cancels last end of map vote")

	if (cstrike_running())
		register_event("TeamScore", "team_score", "a")

	get_localinfo("lastMap", g_lastMap, 31)
	set_localinfo("lastMap", "")

	new maps_ini_file[64]
	get_configsdir(maps_ini_file, 63);
	format(maps_ini_file, 63, "%s/maps.ini", maps_ini_file);
	
	if (!file_exists(maps_ini_file))
		get_cvar_string("mapcyclefile", maps_ini_file, 63)
	if (loadSettings(maps_ini_file))
		set_task(20.0, "voteNextmap", 987456, "", 0, "b")  //15

	g_coloredMenus = colored_menus()
}

public checkVotes()
{
	new b = 0
	
	for (new a = 0; a < g_mapVoteNum; ++a)
		if (g_voteCount[b] < g_voteCount[a])
			b = a
	
	if (g_voteCount[SELECTMAPS] > g_voteCount[b] && g_voteCount[SELECTMAPS] > g_voteCount[SELECTMAPS+1])
	{
		new mapname[32]
		
		get_mapname(mapname, 31)
		new Float:steptime
		
		if(equali(mapname, "dod_avalanche") || equali(mapname, "dod_hill_classic"))
			steptime = get_cvar_float("amx_extendmap_step2")
		else
			steptime = get_cvar_float("amx_extendmap_step")
			
		set_cvar_float("mp_timelimit", get_cvar_float("mp_timelimit") + steptime)
		
		client_print(0, print_chat, "%L", LANG_PLAYER, "CHO_FIN_EXT", steptime, get_cvar_float("mp_timelimit"))
		log_amx("Vote: Voting for the nextmap finished. Map %s will be extended to next %.0f minutes", mapname, steptime)
		
		return
	}
	
	if (g_voteCount[b] && g_voteCount[SELECTMAPS + 1] <= g_voteCount[b])
		set_cvar_string("amx_nextmap", g_mapName[g_nextName[b]])
	
	new smap[32]
	
	get_cvar_string("amx_nextmap", smap, 31)
	client_print(0, print_chat, "%L", LANG_PLAYER, "CHO_FIN_NEXT", smap)
	log_amx("Vote: Voting for the nextmap finished. The nextmap will be %s", smap)
}

public countVote(id, key)
{
	if (get_cvar_float("amx_vote_answers"))
	{
		new name[32]
		get_user_name(id, name, 31)
		
		if (key == SELECTMAPS)
			client_print(0, print_chat, "%L", LANG_PLAYER, "CHOSE_EXT", name)
		else if (key < SELECTMAPS)
			client_print(0, print_chat, "%L", LANG_PLAYER, "X_CHOSE_X", name, g_mapName[g_nextName[key]])
	}
	++g_voteCount[key]
	
	return PLUGIN_HANDLED
}

bool:isInMenu(id)
{
	for (new a = 0; a < g_mapVoteNum; ++a)
		if (id == g_nextName[a])
			return true
	return false
}

public voteNextmap()
{
	new winlimit = get_cvar_num("mp_winlimit")
	new maxrounds = get_cvar_num("mp_maxrounds")
	
	if (winlimit)
	{
		new c = winlimit - 2
		
		if ((c > g_teamScore[0]) && (c > g_teamScore[1]))
		{
			g_selected = false
			return
		}
	}
	else if (maxrounds)
	{
		if ((maxrounds - 2) > (g_teamScore[0] + g_teamScore[1]))
		{
			g_selected = false
			return
		}
	} else {
		new timeleft = get_timeleft()
		
		if (timeleft < 1 || timeleft > 129)
		{
			g_selected = false
			return
		}
	}

	if (g_selected)
		return

	g_selected = true
	
	new menu[512], a, mkeys = (1<<SELECTMAPS + 1)
	new pos = format(menu, 511, g_coloredMenus ? "\y%L:\w^n^n" : "%L:^n^n", LANG_SERVER, "CHOOSE_NEXTM")
	new dmax = (g_mapNums > SELECTMAPS) ? SELECTMAPS : g_mapNums
	
	g_voteCount[SELECTMAPS] = 0
	g_voteCount[SELECTMAPS + 1] = 0
	
	new mapname[32]
	get_mapname(mapname, 31)
	
	if(equali(mapname, "dod_hill_classic"))
		{
		if ((winlimit + maxrounds) == 0 && (get_cvar_float("mp_timelimit") < get_cvar_float("amx_extendmap_max2")))
			{
			pos += format(menu[pos], 511, g_coloredMenus ? "\y%d. \r%L^n" : "%d. %L^n", SELECTMAPS + 1, LANG_SERVER, "EXTED_MAP", mapname)
			mkeys |= (1<<SELECTMAPS)
			}
		}
	else
		{
		if ((winlimit + maxrounds) == 0 && (get_cvar_float("mp_timelimit") < get_cvar_float("amx_extendmap_max")))
			{
			pos += format(menu[pos], 511, g_coloredMenus ? "\y%d. \r%L^n" : "%d. %L^n", SELECTMAPS + 1, LANG_SERVER, "EXTED_MAP", mapname)
			mkeys |= (1<<SELECTMAPS)
			}
		}
	
	menu[pos++] = '^n'
	
	for (g_mapVoteNum = 0; g_mapVoteNum < dmax; ++g_mapVoteNum)
	{
		if(g_mapVoteNum == 0 && !equali(mapname, "dod_avalanche"))
			{
			for(a = 0; a < g_mapNums;)
				{
				if(equali(g_mapName[a], "dod_avalanche"))
					break
				else
					a++
				}
			}
		else
			a = random_num(0, g_mapNums - 1)
	
		
		while (isInMenu(a))
			if (++a >= g_mapNums) a = 0
		
		g_nextName[g_mapVoteNum] = a
		pos += format(menu[pos], 511, g_coloredMenus ? "\w%d. \dmodified %s^n" : "%d. modified %s^n", g_mapVoteNum + 1, g_mapName[a])
		mkeys |= (1<<g_mapVoteNum)
		g_voteCount[g_mapVoteNum] = 0
	}
	
	menu[pos++] = '^n'

	if(equali(mapname, "dod_hill_classic"))
		{
		if ((winlimit + maxrounds) == 0 && (get_cvar_float("mp_timelimit") < get_cvar_float("amx_extendmap_max2")))
			{
			pos += format(menu[pos], 511, g_coloredMenus ? "\y%d. \r%L^n" : "%d. %L^n", SELECTMAPS + 1, LANG_SERVER, "EXTED_MAP", mapname)
			mkeys |= (1<<SELECTMAPS)
			}
		}
	else
		{
		if ((winlimit + maxrounds) == 0 && (get_cvar_float("mp_timelimit") < get_cvar_float("amx_extendmap_max")))
			{
			pos += format(menu[pos], 511, g_coloredMenus ? "\y%d. \r%L^n" : "%d. %L^n", SELECTMAPS + 1, LANG_SERVER, "EXTED_MAP", mapname)
			mkeys |= (1<<SELECTMAPS)
			}
		}
	
	menu[pos++] = '^n'

	//format(menu[pos], 511, g_coloredMenus ? "\w0. \ymodified avalanche" : "0. modified avalanche")

	new MenuName[64]
	
	format(MenuName, 63, "/w%L", "en", "CHOOSE_NEXTM")
	show_menu(0, mkeys, menu, 25, MenuName)
	set_task(25.0, "checkVotes", 99423781)
	client_print(0, print_chat, "%L", LANG_SERVER, "TIME_CHOOSE")
	client_cmd(0, "spk ^"gman/(p85) gman_choose1^"")
	log_amx("Vote: Voting for the next fucking map started")
}

loadSettings(filename[])
{
	if (!file_exists(filename))
		return 0

	new szText[32]
	new a, pos = 0
	new currentMap[32]
	
	get_mapname(currentMap, 31)

	while ((g_mapNums < MAX_MAPS) && read_file(filename, pos++, szText, 31, a))
	{
	//	if(equali(currentMap, "dod_avalanche"))
	//		{
	//		if(szText[0] != ';' && parse(szText, g_mapName[g_mapNums], 31) && is_map_valid(g_mapName[g_mapNums]) && !equali(g_mapName[g_mapNums], currentMap))
	//			++g_mapNums
	//		}
	//	else
	//		{  
			if(szText[0] != ';' && parse(szText, g_mapName[g_mapNums], 31) && is_map_valid(g_mapName[g_mapNums]) && !equali(g_mapName[g_mapNums], currentMap))
				++g_mapNums
	//		}
	}

	return g_mapNums
}

public cmdCancelVote(id, level, cid)
{
	if (!cmd_access(id, level, cid, 0))
		return PLUGIN_HANDLED

	if (task_exists(99423781, 1))
	{
		new authid[32], name[32]
		
		get_user_authid(id, authid, 31)
		get_user_name(id, name, 31)
		log_amx("Vote: ^"%s<%d><%s><>^" cancel vote session", name, get_user_userid(id), authid)
		
		new players[32], pnum, lTag[16], activity = get_cvar_num("amx_show_activity")
		get_players(players, pnum, "c")
		
		for (new i = 0; i < pnum;i ++)
		{
			format(lTag, 15, "%L", players[i], is_user_admin(id) ? "ADMIN" : "PLAYER")
			switch (activity)
			{
				case 2: client_print(players[i], print_chat, "%L", LANG_PLAYER, "ADMIN_CANC_VOTE_2", lTag, name)
				case 1: client_print(players[i], print_chat, "%L", LANG_PLAYER, "ADMIN_CANC_VOTE_1", lTag)
			}
		}
		
		console_print(id, "%L", id, "VOTING_CANC")
		client_print(id,print_chat,"%L",LANG_PLAYER,"VOTING_CANC")
		remove_task(99423781, 1)
		//set_cvar_float("amx_last_voting", get_gametime())
	}
	else
		console_print(id, "%L", id, "NO_VOTE_CANC")

	return PLUGIN_HANDLED
}

public team_score()
{
	new team[2]
	
	read_data(1, team, 1)
	g_teamScore[(team[0]=='C') ? 0 : 1] = read_data(2)
}

public plugin_end()
{
	new current_map[32]

	get_mapname(current_map, 31)
	set_localinfo("lastMap", current_map)
}
